package com.hup.joystick.service.jna;

import com.hup.utils.commons.JniUtil;
import com.sun.jna.Library;

/**
 * 符合JNA特性的dll映射类;
 *
 * @apiNote 此类的业务方法调用前, 要进行初始化: {@link #createDirectInput8(boolean, DeviceStateCallback)},
 * 如果没有初始化,则dll函数内也会抛出异常HResult,所以上层服务类也无需在每个方法中检查是否已初始化;
 */
public interface JoystickJnaLib extends Library {
    JoystickJnaLib INSTANCE = JniUtil.loadLibraryJNA("/dll/JoystickJna.dll", JoystickJnaLib.class);

    /**
     * dll版本号
     */
    String version();

    /**
     * 初始化API
     *
     * @param isUtf8 程序运行时的字符串编码:idea开发时是UTF8,window运行时是GBK;没找到cpp中直接获取运行时编码的函数,所以由java传参
     */
    int createDirectInput8(boolean isUtf8, DeviceStateCallback deviceStateCallback);

    /**
     * 释放对象
     */
    void doFree();

    /**
     * 查询已连接设备(DI8DEVCLASS_GAMECTRL)
     *
     * @return hr
     */
    int enumDevices(EnumDeviceCallback callback);

    /**
     * 开始监听设备按键;
     * .指令成功时,会阻塞当前线程;
     * .指令执行结果和轮询状态都在 {@link DeviceStateCallback#onDeviceState(DIJoyState2, int)}中返回
     * https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ee417897(v=vs.85)
     *
     * @param guid {@link EnumDeviceData#guid}
     * @param stateScanSpan 轮询间隔ms,如1000/n代表每秒最多返回n帧不同的数据
     * @param stickRange 摇杆的返回值范围=±stickRange,如1000
     * @param breakIfErr true-成功轮询监听后,如果出现错误就退出轮询;一般为false,则设备丢失后不用调用重连代码;
     * @apiNote 如果breakIfErr=true时,设备断开后,会返回两次Lost状态!
     */
    void startListenState(String guid, int stateScanSpan, int stickRange, boolean breakIfErr);

    /**
     * 停止按键监听
     */
    void stopListenState();


}